package com.allwees.bs.c.module.payment.service.impl;


import com.allwees.bs.c.module.order.dto.OrderDTO;
import com.allwees.bs.c.module.order.entity.OrderEntity;
import com.allwees.bs.c.module.order.repository.OrderRepository;
import com.allwees.bs.c.module.order.service.IOrderService;
import com.allwees.bs.c.module.payment.dto.CodDTO;
import com.allwees.bs.c.module.payment.req.PaymentCodReq;
import com.allwees.bs.c.module.payment.req.SmsCodeReq;
import com.allwees.bs.c.module.payment.service.ICodPaymentService;
import com.allwees.bs.core.model.user.context.CurrentUser;
import com.allwees.bs.core.modelbase.constant.ResultCode;
import com.allwees.bs.core.modelbase.constant.ResultEnum;
import com.allwees.bs.core.modelbase.exception.BusinessException;
import com.allwees.core.common.i18n.I18nMessage;
import com.allwees.core.common.util.MoneyUtil;
import com.allwees.core.common.util.http.RequestContext;
import com.allwees.sender.sms.SmsCodeVerifier;
import com.allwees.sender.sms.SmsSender;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.MessageFormat;

@Slf4j
@Service
public class CodPaymentServiceImpl implements ICodPaymentService {

    /**
     * 使用COD门槛
     */
    @Value("${system.params.order.cod.leastCodAmt:0}")
    private String leastCodAmt;

    @Value("${system.params.order.cod.isPhoneCheck:true}")
    private boolean isPhoneCheck;

    @Autowired
    private I18nMessage i18nMessage;

    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    private IOrderService orderService;

    @Autowired
    private SmsSender smsSender;

    @Autowired
    private SmsCodeVerifier verifier;

    @Override
    public OrderDTO codOrder(PaymentCodReq req) {
        if (isPhoneCheck) {
            verifier.verify("COD_PAY", req.getPhone().replace("(","").replace(")",""), req.getCode());
        }
        CodDTO codDTO = checkCod(req);
        return  orderService.payOrderByCOD((OrderEntity)codDTO.getOrder());
    }

    @Override
    public CodDTO checkCod(PaymentCodReq req) {
        OrderEntity order = this.orderRepository.getByUuid(req.getOrderUuid());
        if (order == null) {
            throw BusinessException.getInstance(ResultEnum.NOT_FOUND);
        }
        String value = this.leastCodAmt;
        if (StringUtils.isBlank(value) || !NumberUtils.isCreatable(value)) {
            throw BusinessException.getInstance(ResultEnum.PARAM_ERROR);
        }
        BigDecimal codFree = new BigDecimal(value).setScale(2, BigDecimal.ROUND_HALF_UP);
        if (order.getAmtProductAfterAdd().compareTo(codFree) < 0) {
            BigDecimal deduct = MoneyUtil.sub(codFree, order.getAmtProductAfterAdd());
            String errorMsg = i18nMessage.getCodPayError();
            errorMsg = MessageFormat.format(errorMsg, deduct.toPlainString());
            throw BusinessException.getInstance(ResultCode.PAYMENT_COD_PAY_ERROR, errorMsg);
        }
        if (!order.getUserUuid().equals(CurrentUser.getUser().getUserUuid())) {
            return null;
        }
        return  CodDTO.builder().isPhoneCheck(isPhoneCheck).order(order).build();
    }

    @Override
    public void sendSmsCode(SmsCodeReq smsCodeReq) {
        OrderEntity order = this.orderRepository.getByUuid(smsCodeReq.getOrderUuid());
        if (order == null) {
            throw BusinessException.getInstance(ResultEnum.NOT_FOUND);
        }

        if (!smsCodeReq.getPhone().equals(order.getShippingAddressPhone())) {
            throw BusinessException.getInstance(ResultEnum.NOT_FOUND);
        }
        if (!order.getUserUuid().equals(CurrentUser.getUser().getUserUuid())) {
            return ;
        }
        smsSender.sendSms("COD_PAY",smsCodeReq.getPhone().replace("(","").replace(")",""),RequestContext.getRemoteAddr());
    }

}
